package com.inns.position.kafka.bean;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.inns.position.hbase.HbaseConsts;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Created by phoenix on 2018/4/21.
 */
public class LocationRealTimeInfo {

    private static final boolean DAY_REVISE = true;// true 代表每天只统计一次，false 统计粒度更细，每天可以统计多次
    private String floorId;
    private Integer poiId;
    private float x;
    private float y;
    private Long lastUpdateTime;
    private List<TimePair> allAccessTimes = new ArrayList<>();

    public LocationRealTimeInfo() {
    }

    public LocationRealTimeInfo(LocationInfo locationInfo) {
        update(locationInfo);
    }

    public void update(LocationInfo locationInfo) {
        this.floorId = locationInfo.getFloorId();
        this.poiId = locationInfo.getPoiId();
        this.x = locationInfo.getX();
        this.y = locationInfo.getY();
        if (isNewAccess(locationInfo)) {
            // 看作新一次的访问
            this.allAccessTimes.add(new TimePair(locationInfo.getTimestamp()));
        } else {
            // 在线用户，时间累加
            TimePair timePair = getLastAccessTime();
//            timePair.setDurTime(locationInfo.getTimestamp() - timePair.getStartTime());
            timePair.setDurTime(timePair.getDurTime() + 2000);
        }
        this.lastUpdateTime = locationInfo.getTimestamp();
    }

    public boolean isNewAccess(LocationInfo locationInfo) {
        return lastUpdateTime == null || getDayOfYear(locationInfo.getTimestamp()) != getDayOfYear(lastUpdateTime);
//        return lastUpdateTime == null || locationInfo.getTimestamp() - lastUpdateTime > HbaseConsts.SPLIT_TIME();
    }

    public String getFloorId() {
        return floorId;
    }

    public void setFloorId(String floorId) {
        this.floorId = floorId;
    }

    public Integer getPoiId() {
        return poiId;
    }

    public void setPoiId(Integer poiId) {
        this.poiId = poiId;
    }


    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }

    public Long getLastUpdateTime() {
        return lastUpdateTime;
    }

    public void setLastUpdateTime(Long lastUpdateTime) {
        this.lastUpdateTime = lastUpdateTime;
    }

    public List<TimePair> getAllAccessTimes() {
        return getAccessTimesByStartTime(System.currentTimeMillis() - HbaseConsts.SIX_MONTH);
    }

    @JsonIgnore
    public TimePair getLastAccessTime() {
        return this.allAccessTimes.get(allAccessTimes.size() - 1);
    }

    /**
     * 返回指定时间内的访问时间，如一个月内
     *
     * @param startTime
     * @return
     */
    public List<TimePair> getAccessTimesByStartTime(long startTime) {
        List<TimePair> result = new ArrayList<>();
        for (TimePair timePair : allAccessTimes) {
            if (timePair.getStartTime() > startTime) {
                result.add(timePair);
            }
        }
//        return result;
        return reviseAccessTimes(result);
    }

    public List<TimePair> getAccessTimesByTimeInterval(long startTime, long endTime) {
        List<TimePair> result = new ArrayList<>();
        for (TimePair timePair : allAccessTimes) {
            if (timePair.getStartTime() >= startTime && timePair.getStartTime() < endTime) {
                result.add(timePair);
            }
        }
//        return result;
        return reviseAccessTimes(result);
    }

    public long getTotalAccessTime(long startTime, long endTime) {
        long sumTime = 0;
        for (TimePair timePair : allAccessTimes) {
            if (timePair.getStartTime() >= startTime && timePair.getStartTime() < endTime) {
                if (endTime - timePair.getStartTime() > timePair.getDurTime()) {
                    sumTime += timePair.getDurTime();
                } else {
                    sumTime += endTime - timePair.getStartTime();
                }
            }
        }
        return sumTime;
    }

    /**
     * 返回指定时间以前的访问时间，如一个月之前
     *
     * @param endTime
     * @return
     */
    public List<TimePair> getAccessTimesByEndTime(long endTime) {
        List<TimePair> result = new ArrayList<>();
        for (TimePair timePair : allAccessTimes) {
            if (timePair.getStartTime() < endTime) {
                result.add(timePair);
            }
        }
//        return result;
        return reviseAccessTimes(result);
    }

    public void setAllAccessTimes(List<TimePair> allAccessTimes) {
        this.allAccessTimes = allAccessTimes;
    }

    @JsonIgnore
    public List<TimePair> reviseAccessTimes(List<TimePair> oldList) {
        if (!DAY_REVISE) {
            return oldList;
        }
        List<TimePair> list = new ArrayList<>();
        int lastDay = 0;
        for (TimePair timePair : oldList) {
            int i = getDayOfYear(timePair.getStartTime());
            if (lastDay == i) {
                TimePair timePair1 = list.get(list.size() - 1);
                timePair1.setDurTime(timePair1.getDurTime() + timePair.getDurTime());
            } else {
                list.add(timePair);
            }
            lastDay = i;
        }
        return list;
    }

    private int getDayOfYear(long time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        return calendar.get(Calendar.DAY_OF_YEAR);
    }
}
